﻿/*
 * @Autor: PK
 * @Date: 2022/01/14 22:13:SS
 */

using System.Collections.Generic;
using O2DESNet;
using ShkSimulation.core.dao.statistic;
using ShkSimulation.carsharing;
using ShkSimulation.core.template.customer;
using ShkSimulation.core.template.model;

namespace ShkSimulation.carsharing.demo {

	public class DemoStation: CarsharingStation {
		
		public int RejectCount { get; set; }
		public int ArriveCount { get; set; }
		public int DepartCount { get; set; }
		public int FinishedCount { get; private set; }

		public int VehicleCount { get; set; }
		
		public HourCounter TravelTime { get; set; }

		private Queue<CarsharingVehicle> Vehicles = new Queue<CarsharingVehicle>();

		private Dictionary<string, ReadOnlyHourCounter> NamedHourCounters = new Dictionary<string, ReadOnlyHourCounter>();

		public DemoStation(BaseAgencyParams agencyParams, int vehicleCount) : base(agencyParams) {
			for (int i = 0; i < vehicleCount; i++) {
				Vehicles.Enqueue(new DemoVehicle(i));
			}
			VehicleCount = vehicleCount;
			TravelTime = AddHourCounter();
			NamedHourCounters.Add("顾客旅行时间", TravelTime.AsReadOnly());
		}

		public override ServiceRateHelper ServiceRateHelper { get; set; }

		public override DataReportInfo GetReportInfo() {
			Dictionary<string, double> doubleValues = new Dictionary<string, double>();
			doubleValues.Add("ArriveCount", ArriveCount);
			doubleValues.Add("RejectCount", RejectCount);
			doubleValues.Add("FinishedCount", FinishedCount);
			return DataReportInfo.Create(UniqueId.ToString(), ClockTime, NamedHourCounters, doubleValues);
		}

		public override void TravelerArrive(CarsharingTraveler customer) {
			// Console.WriteLine($"车站{UniqueId}到达顾客 {ClockTime}");
			DemoTraveler traveler = (DemoTraveler)customer;
			if (traveler.Vehicle != null) {
				FinishedCount++;
				VehicleCount++;
				TravelTime.ObserveCount((ClockTime - traveler.StartTime).TotalMinutes, ClockTime);
				Vehicles.Enqueue(traveler.Vehicle);
				traveler.Vehicle.UntieCustomer();
				return;
			}
			ArriveCount++;
			if (Vehicles.Count == 0) {
				RejectCount++;
				return;
			}
			CarsharingVehicle vehicle = Vehicles.Dequeue();
			traveler.StartTime = ClockTime;
			vehicle.BindCustomer(customer);
			InternalServe(traveler);
		}

		public override void TravelerServe(CarsharingTraveler customer) {
			// Console.WriteLine($"车站{UniqueId} 服务顾客 {ClockTime}");
			ScheduleDepart(customer, ServiceRateHelper.GetAverageServiceTime());
		}

		public override void TravelerDepart(CarsharingTraveler customer) {
			// Console.WriteLine($"车站{UniqueId} 离开顾客 {ClockTime}");
			DepartCount++;
			VehicleCount--;
			customer.EnterNextAgency();
		}

	}

}